/**
 * @file
 * @brief This file contains common types definitions for the logging API.
 *
 * @attention Due to limitation of the C++ language, some internal implementation
 * (e.g. the function bodies) are coded directly into this header file.
 * Such code is NOT meant to be used or referred to by a user directly,
 * and is subject to CHANGE WITHOUT NOTICE.
 * Therefore DO NOT DEPEND ON any implementation details!
 */

#ifndef LOG_COMMON_H
#define LOG_COMMON_H

#include <cstdint>
#include <type_traits>

namespace netaos {
namespace nosal {
namespace log {

/**
 * @defgroup common Common Types
 * @brief Common type definitions for the logging API.
 */

/// @addtogroup common
/// @{

/**
 * @brief Log levels, in decreasing order of severity.
 *
 * Maps one-by-one to the values from DltLogLevelType.
 * @sa <dlt/dlt_types.h>
 *
 * @uptrace{SWS_LOG_00018, d6cc8ea90d84cb6066b82fc0e8fd055893b0c954}
 */
enum class LogLevel : std::uint8_t
{
    kOff = 0x00,  ///< No logging
    kFatal = 0x01,  ///< Fatal error, not recoverable
    kError = 0x02,  ///< Error with impact to correct functionality
    kWarn = 0x03,  ///< Warning if correct behavior cannot be ensured
    kInfo = 0x04,  ///< Informational, providing high level understanding
    kDebug = 0x05,  ///< Detailed information for programmers
    kVerbose = 0x06  ///< Extra-verbose debug messages (highest grade of information)
};

/**
 * @brief Log mode. Flags, used to configure the sink for log messages.
 * @note In order to combine flags, at least the OR and AND operators needs to be provided for this type.
 */
enum class LogMode : std::uint8_t
{
    kRemote = 0x01,  ///< Send remotely
    kFile = 0x02,  ///< Save to file
    kConsole = 0x04,  ///< Forward to console
};

namespace internal
{

/**
 * @brief LogReturn. Flags to define return values.
 * @note This is required to hide include/implementation of dlt on exported headers
 *
 * Maps one-by-one to the values from DltReturnValue.
 * @sa <dls/dlt_types.h>
 */
enum class LogReturnValue : std::int8_t
{
    kReturnLoggingDisabled = -7,
    kReturnUserBufferFull = -6,
    kReturnWrongParameter = -5,
    kReturnBufferFull = -4,
    kReturnPipeFull = -3,
    kReturnPipeError = -2,
    kReturnError = -1,
    kReturnOk = 0,
    kReturnTrue = 1
};

template <typename EnumT>
constexpr auto to_integral(const EnumT value) noexcept
{
    return static_cast<std::underlying_type_t<EnumT>>(value);
}
}  // namespace internal

inline auto operator|(LogMode lhs, LogMode rhs) noexcept
{
    return (static_cast<LogMode>(internal::to_integral(lhs) | internal::to_integral(rhs)));
}

inline auto operator&(LogMode lhs, LogMode rhs) noexcept
{
    return (internal::to_integral(lhs) & internal::to_integral(rhs));
}

/// @}
} /* namespace log */
} /* namespace nosal */
} /* namespace netaos */

#endif  // LOGCOMMON_H
